import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

/**
 * A class to hold 3 elves that are waiting to get help from santa
 * seqNum field adapted from the Javadoc for PriorityBlockingQueue
 * http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/PriorityBlockingQueue.html
 */
public class ElfGroup implements WinterHelper {
	// List of elves waiting to see Santa
	private List<Elf> elves;
	// For generating seqNums
	final static AtomicLong seq = new AtomicLong();
	// Unique ID for each elf to ensure Queue order
	final long seqNum;

	/**
	 * Creates an elf group for Santa to tend to
	 * 
	 * @param eGroup
	 *            - Array of elves that make up a group
	 */
	public ElfGroup(Elf[] eGroup) {
		
		elves = new ArrayList<Elf>();
		seqNum = seq.getAndIncrement();
		
		for (Elf e : eGroup) {
			elves.add(e);
		}
	}


	/**
	 * Comparator for the elf group when they go to see Santa Elf groups have a
	 * lower priority than reindeer
	 * 
	 * @return 1 if being compared to a reindeer, else 0
	 */
	@Override
	public int compareTo(WinterHelper helper) {
		if (helper.getClass() == Reindeer.class) {
			return 1;
		}

		return (int) (this.seqNum - ((ElfGroup)helper).seqNum);
	}

	/**
	 * Allows Santa to help the group of elves. Santa fixes one else at a time
	 * until there are no more elves left in the group to be fixed.
	 */
	public void helpMe() {

		while (!elves.isEmpty()) {
			Elf removedElf = null;
			
			try {
				Thread.sleep(Properties.ELF_FIX_TIME);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			elves.get(0).getLock().lock();
			
			try {
				removedElf = elves.remove(0);
				removedElf.getCondition().signalAll();
			} finally {
				System.out.println("Santa has helped " + removedElf + ".");
				removedElf.getLock().unlock();
			}
			
		}

	}

	
	/**
	 * Accessor for the elves in the group
	 * 
	 * @return List of elves in the group
	 */
	public List<Elf> getElves() {
		return elves;
	}

	
	/**
	 * Printable string format for an elf group
	 * 
	 * @return Comma separated string of elf names in the group
	 */
	public String toString() {
		String result = "";

		for (int i = 0; i < elves.size(); i++) {
			if (i == 0) {
				result += elves.get(i);
			} else {
				result += ", " + elves.get(i);
			}

		}

		return result;
	}

}